home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / master / Examples / Visual / VMake / vmake.c < prev    next >
C/C++ Source or Header  |  1994-02-01  |  28KB  |  827 lines

  1. #include "vmake.h"
  2. #include "vmake_rev.h"
  3.  
  4. Prototype int CreateWindow(void);
  5. Prototype void DestroyWindow(void);
  6. Prototype char *SkipAss(const char *);
  7.  
  8. void myexit(void);
  9. int main(int, char **);
  10.  
  11. struct GLOBAL global;
  12. __aligned struct FileInfoBlock vmfib;
  13.  
  14. struct Library *GadToolsBase;
  15. struct Library *AslBase;
  16. struct Library *WorkbenchBase;
  17. struct Library *ArpBase;
  18.  
  19. char    *InitialFileName;
  20. char    *ConfigName;
  21. short   StartFromWB;
  22. short   BuildIt;
  23. char    *RexxScript;
  24. char    Buf[256];
  25.  
  26. #define TEMPLATE "PROJECT,REXX/K,CONFIG/K,BUILD/S"
  27.  
  28. ULONG oldSeconds, oldMicros; /* for double click filtering */
  29.  
  30. #define VM_PROJ        0
  31. #define VM_RSCRIPT     VM_PROJ+1
  32. #define VM_CONFIG      VM_RSCRIPT+1
  33. #define VM_BUILD       VM_CONFIG+1
  34. #define OPT_COUNT      VM_BUILD+1
  35.  
  36. long vm_opts[OPT_COUNT];
  37.  
  38. char *RexxHostName = "VMAKE" VERSTAG;
  39.  
  40. /***********************************************************************************
  41.  * Procedure: wbmain
  42.  * Synopsis:  rc = wbmain(WBStartup);
  43.  * Purpose:   Performs appropriate initialization to run program from Workbench
  44.  * Notes:     Parse tooltypes as a command.  Note that we are CD'd into the
  45.  *            application's directory, not the tooltype's icon's dir.
  46.  ***********************************************************************************/
  47. int wbmain(wbs)
  48. struct WBStartup *wbs;
  49. {
  50.    struct DiskObject *dob;
  51.    short i;
  52.    short j;
  53.    short FileSpecified = 0;
  54.    short abortIt = 0;
  55.  
  56.    /*
  57.     *  Search for options, set current directory to last valid
  58.     *  disk object.  Run commands specified by tool types in order
  59.     */
  60.  
  61.    for (i = 0; i < wbs->sm_NumArgs; ++i)
  62.    {
  63.       BPTR saveLock = CurrentDir((BPTR)wbs->sm_ArgList[i].wa_Lock);
  64.  
  65.       if (i == wbs->sm_NumArgs - 1 && FileSpecified == 0)
  66.       {
  67.          InitialFileName = strdup(wbs->sm_ArgList[i].wa_Name);
  68.       }
  69.  
  70.       if (dob = GetDiskObject(wbs->sm_ArgList[i].wa_Name))
  71.       {
  72.          if (dob->do_ToolTypes)
  73.          {
  74.             for (j = 0; dob->do_ToolTypes[j]; ++j)
  75.             {
  76.                char *ptr = dob->do_ToolTypes[j];
  77.  
  78.                if (strnicmp(ptr, "FILE=", 5) == 0)
  79.                {
  80.                   InitialFileName = strdup(SkipAss(ptr));
  81.                   FileSpecified = 1;
  82.                }
  83.                else
  84.                {
  85.                   if (strnicmp(ptr, "REXX=", 5) == 0)
  86.                   {
  87.                      RexxScript = strdup(SkipAss(ptr));
  88.                   }
  89.                   else
  90.                   {
  91.                      if (strnicmp(ptr, "CONFIG=", 7) == 0)
  92.                         ConfigName = strdup(SkipAss(ptr));
  93.                      else
  94.                      {
  95.                         if (strnicmp(ptr, "BUILD", 5) == 0)
  96.                            BuildIt = 1;
  97.                         else
  98.                         {
  99.                            /* These strings are needed for the requester      */
  100.                            global.text[TEXT_OK] = "OK";
  101.                            global.text[TEXT_CANCEL] = "Cancel";
  102.                            /* OK to use any text slot - will get overlaid     */
  103.                            global.text[1] = "Bad ToolType";
  104.                            /* Unfortunately the dos 1.3 version of request()  */
  105.                            /* dies of a contagious plague...                  */
  106.                            if ((DOSBase->dl_lib.lib_Version >= 36) &&
  107.                                !request(0, 1, ptr, NULL))
  108.                            {
  109.                               abortIt = 1;
  110.                               break;
  111.                            }
  112.                         }
  113.                      }
  114.                   }
  115.                }
  116.             }
  117.          }
  118.          FreeDiskObject(dob);
  119.       }
  120.       CurrentDir(saveLock);
  121.       if (abortIt)
  122.           break;
  123.    }
  124.  
  125.    if (abortIt == 0)
  126.    {
  127.       go_dir(wbs->sm_ArgList[wbs->sm_NumArgs-1].wa_Lock);
  128.       setup_cli();
  129.       StartFromWB = 1;
  130.       main(1, NULL);
  131.    }
  132. }
  133.  
  134. /***********************************************************************************
  135.  * Procedure: main
  136.  * Synopsis:  rc = main(argc, argv)
  137.  * Purpose:   The main entry point for the program
  138.  ***********************************************************************************/
  139. int main(int argc, char **argv)
  140. {
  141.    struct IntuiMessage *msg;
  142.    struct RDargs *rdargs;
  143.  
  144.    if (!StartFromWB)
  145.    {
  146.       if (DOSBase->dl_lib.lib_Version >= 36)
  147.       {
  148.          rdargs = ReadArgs(TEMPLATE, vm_opts, NULL);
  149.          if (rdargs == NULL)
  150.             PrintFault(IoErr(), NULL);
  151.          else
  152.          {           
  153.             InitialFileName = (char *)vm_opts[VM_PROJ];
  154.             RexxScript = (char *)vm_opts[VM_RSCRIPT];
  155.             ConfigName = (char *)vm_opts[VM_CONFIG];
  156.             BuildIt = vm_opts[VM_BUILD];
  157.          }
  158.       }
  159.       else
  160.       {
  161.          if (argc != 1)
  162.          {
  163.             InitialFileName = argv[1];
  164.          }
  165.       }
  166.    }
  167.  
  168.    /*
  169.     *   Open GadToolsBase/AslBase manually so we don't exit if they
  170.     *   don't exist.
  171.     */
  172.  
  173.    GadToolsBase  = OpenLibrary("gadtools.library", 0);
  174.    AslBase       = OpenLibrary("asl.library", 0);
  175.    WorkbenchBase = OpenLibrary("workbench.library", 0);
  176.  
  177.    memset(&global, 0, sizeof(global));
  178.  
  179.    if (AslBase != NULL)
  180.    /* Amigados version 2.0 or greater */
  181.    {
  182.       global.cbufsize = CBUF_SIZE_20; /* Long command lines */
  183.       global.freq = AllocFileRequest();
  184.    }
  185.    else
  186.    /* Amigados version 1.3 */
  187.    {
  188.       global.cbufsize = CBUF_SIZE_13; /* Short command lines */
  189.       ArpBase = OpenLibrary("arp.library", 0);
  190.       if (ArpBase != NULL)
  191.          global.freq = ArpAllocFreq();
  192.    }
  193.  
  194.    global.cbuf = malloc(global.cbufsize+1);
  195.    global.rexxrs = malloc(global.cbufsize+1);
  196.    if ((global.cbuf == NULL) || (global.rexxrs == NULL))
  197.       return(20); /* not enough memory to run & no good way to say why not */
  198.  
  199.    if (ConfigName)
  200.    {
  201.       global.parsefail = parse_config(ConfigName);
  202.       if (!global.parsefail)
  203.          Sym_Set(SYM_CONFIG, ConfigName, NULL);
  204.    }
  205.    else
  206.    {
  207.       global.parsefail = parse_config(ALT_CONFIG_FILE);
  208.       if (!global.parsefail)
  209.          Sym_Set(SYM_CONFIG, ALT_CONFIG_FILE, NULL);
  210.       else
  211.       {
  212.          if (global.parsefail == 2)
  213.          {
  214.             global.parsefail = parse_config(CONFIG_FILE);
  215.             if (!global.parsefail)
  216.                Sym_Set(SYM_CONFIG, CONFIG_FILE, NULL);
  217.          }
  218.       }
  219.    }
  220.  
  221.    if (!global.parsefail)
  222.       strcpy(global.title, global.text[TEXT_NOPROJ]);
  223.    Sym_Set(SYM_ORIG_CFG, Sym_Lookup(SYM_CONFIG), 0);
  224.  
  225.    {
  226.       /* We need to make the rexx port name available for them to use */
  227.       char *pname;
  228.       GetDiceRexxPortSlot(NULL, &pname);
  229.       if (pname != NULL)
  230.          Sym_Set(SYM_REXXPORT, pname, NULL);
  231.    }
  232.    /* REXX mode is initially non-interactive */
  233.    global.rexxinter = 0;
  234.    Sym_Set(SYM_REXXINTER, "OFF", NULL);
  235.  
  236. while (!global.done)
  237. {
  238.    /* global.screen is initialized to NULL to open on workbench screen */
  239.    /* stay in screen/window loop till reset by JUMP */
  240.    global.newscreen = 0;
  241.  
  242.    if(global.parsefail)
  243.    {
  244.       memset(global.menuitem, 0, sizeof(global.menuitem));
  245.       global.gadlist = NULL; /* doesn't happen when we freegadlist() */
  246.    }
  247.  
  248.    FillIn_RenderInfo(&global.ri, global.screen);
  249.  
  250.    /* Provide a default height/width so that we will get any errors displayed well */
  251.    global.width = global.ri.ScreenWidth-50;
  252.    global.height = global.ri.WindowTitle;
  253.  
  254.    global.ri.WindowTitle  += MARGIN_TOP;
  255.    global.ri.WindowLeft   += MARGIN_LEFT;
  256.    global.ri.WindowRight  += MARGIN_RIGHT + RESIZE_WIDTH;
  257.    global.ri.WindowBottom += MARGIN_BOTTOM;
  258.  
  259.    if (!global.parsefail)
  260.       if (!init_gad_sizes(global.ri.ScreenWidth, global.ri.ScreenHeight,0))
  261.       {
  262.          init_gadgets();
  263.       }
  264.  
  265.    if (!CreateWindow())
  266.    {
  267.       struct AppWindow *appwindow;
  268.       struct MsgPort *appmsgport;
  269.       struct AppMessage *appmsg;
  270.       long   waitflags = 1 << global.window->UserPort->mp_SigBit;
  271.  
  272.       if (WorkbenchBase && (WorkbenchBase->lib_Version >= 36))
  273.       {
  274.          if (appmsgport = CreateMsgPort())
  275.             appwindow = AddAppWindowA(
  276.                            1,     /* userID */
  277.                            0,     /* ptr to userdata, prototyped as long */
  278.                            global.window, appmsgport, /*obvious*/
  279.                            NULL   /* taglist */
  280.                         );
  281.          if (appwindow) waitflags |= 1 << appmsgport->mp_SigBit;
  282.       }
  283.       else
  284.       {
  285.          appwindow  = NULL;
  286.          appmsgport = NULL;
  287.       }
  288.  
  289.       waitflags |= 1 << RexxSigBit;
  290.  
  291.       set_gadgets(1);
  292.  
  293.       if (InitialFileName && !global.parsefail)
  294.       {
  295.          strcpy(global.filename, InitialFileName);
  296.          do_command("READ");
  297.       }
  298.  
  299.       /* ensure that console is available for REXX scripts etc. -- we're    */
  300.       /* either first time in or jumping to a new screen                    */
  301.       TermSession();
  302.       InitSession();
  303.  
  304.       if (RexxScript && !global.parsefail)
  305.       {
  306.          char buf[256];
  307.          sprintf(buf, "ADDR REXX %s %%(_PORT_) %s",
  308.                       RexxScript, global.filename);
  309.          do_command(buf);
  310.       }
  311.  
  312.       /* If there's no project loaded now, we need to ghost most menu items */
  313.       /* and cover the window so they can't play with the gadgets.          */
  314.       if ((global.filename[0] == 0) && !global.parsefail)
  315.       {
  316.          ghost_menus();
  317.          cover_window(); 
  318.       }
  319.       else   /* We have a project, do they want to build it right away?     */
  320.          if (BuildIt && !global.parsefail)
  321.             do_command(global.text[CONFIG_BUILD]);
  322.  
  323.       /* only use these on the first pass */ 
  324.       InitialFileName = RexxScript = NULL;
  325.       BuildIt = 0;
  326.  
  327.       while(!global.done  && !global.newscreen)
  328.       {
  329.          long mask;
  330.  
  331.          global.unghost = 0; /* will get set if we excute NEW or READ */
  332.  
  333.          mask = Wait(waitflags);
  334.          while(msg = (struct IntuiMessage *)GetMsg(global.window->UserPort))
  335.          {
  336.             ULONG class;
  337.             APTR iaddr;
  338.             USHORT code;
  339.             USHORT qual;
  340.             ULONG  Seconds, Micros;
  341.             struct XItem *xitem;
  342.  
  343.             code = msg->Code;
  344.             class = msg->Class;
  345.             iaddr = msg->IAddress;
  346.             qual  = msg->Qualifier;
  347.             Seconds = msg->Seconds;
  348.             Micros = msg->Micros;
  349.  
  350.             ReplyMsg((struct Message *)msg);
  351.  
  352.             switch(class)
  353.             {
  354.                case CLOSEWINDOW:
  355.                   do_command("QUIT");
  356.                   break;
  357.                case GADGETDOWN:
  358.                   /* We will only get this message from s list slider gadget  */
  359.                   /* but should really verify ... oh well                     */
  360.                   global.mouseprop = 1; /* streamline prop gadget handling    */
  361.                   ReportMouse(1, global.window);
  362.                   break;
  363.                case GADGETUP:
  364.                {
  365.                   int doubleclick;
  366.                   
  367. /* really want a reasonable way to initialize oldSecs/Micros for first call... */
  368.                   if (class == GADGETUP)
  369.                   {
  370.                      doubleclick = DoubleClick(oldSeconds, oldMicros,
  371.                                                Seconds, Micros);
  372.                      oldSeconds = Seconds;
  373.                      oldMicros = Micros;
  374.                   }
  375.                   handle_hit((struct Gadget *)iaddr,
  376.                       (qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) ? 1 : 0,
  377.                       doubleclick);
  378.                   /* restore this after mouse dragging stops to avoid an      */
  379.                   /* extra screen flash.                                      */
  380.                   global.mouseprop = 0; /* do gadget hits from now on */
  381.                   ReportMouse(0, global.window);
  382.                   break;
  383.                }
  384.                case NEWSIZE:
  385.                   set_gadgets(0);
  386.                   free_gadlist(global.gadlist);
  387.                   init_gad_sizes(global.window->Width,
  388.                                  global.window->Height, 1);
  389.                   init_gadgets();
  390.                   SetBPen(global.rp, 0);
  391.                   SetAPen(global.rp, 0);
  392. /* debug - original
  393.                   RectFill( global.rp, global.ri.WindowLeft, global.ri.WindowTitle,
  394.                          global.window->Width  - global.ri.WindowRight + MARGIN_RIGHT - 1,
  395.                          global.window->Height - global.ri.WindowBottom + MARGIN_BOTTOM - 1);
  396. */
  397.                   RectFill( global.rp, global.ri.WindowLeft - MARGIN_LEFT,
  398.                          global.ri.WindowTitle,
  399.                          global.window->Width  - global.ri.WindowRight + MARGIN_RIGHT - 1,
  400.                          global.window->Height - global.ri.WindowBottom + MARGIN_BOTTOM - 1);
  401.                   set_gadgets(1);
  402.                   RefreshWindowFrame(global.window);
  403.                   break;
  404.                case MENUPICK:
  405.                   while (code != MENUNULL)
  406.                   {
  407.                      xitem = (struct XItem *)
  408.                              ItemAddress(global.menu, code);
  409.                      do_command(xitem->userdata);
  410.                      code = xitem->item.NextSelect;
  411.                   }
  412.                   break;
  413.                case VANILLAKEY:
  414. #ifdef DBG_JGM
  415.                   printf("Key:%d '%c'\n", code, code);
  416. switch (code)
  417. {
  418. case 'c':
  419.    mark_clean();
  420.    printf("set all objects clean\n");
  421.    break;
  422. case 'd':
  423.    {
  424.    int dirty;
  425.    dirty = test_dirty();
  426.    printf("Dirty state is %d\n", dirty);
  427.    break;
  428.    }
  429. case 'g':
  430.    ghost_menus();
  431.    break;
  432. case 'u':
  433.    unghost_menus();
  434.    break;
  435. }
  436. #endif
  437.  
  438.                   break;
  439.                case MOUSEMOVE:
  440.                   if (global.mouseprop == 1)
  441.                      handle_list(global.filelist, global.filelist->slider, 
  442.                                  CLASS_PROP, NULL, 0);
  443.                   break;
  444. /*
  445. default:
  446.    printf("Unknown IntuiMessage class %d\n", class);
  447.    break;
  448. */
  449.             }
  450.          }
  451.  
  452.          if (appwindow && global.filelist)
  453.          /* Must be Dos 2.0 or greater and must have list structure to put  */
  454.          /* file names into                                                 */
  455.          {
  456.             char appwinbuff[256];
  457.  
  458.             while (appmsg = (struct AppMessage *)GetMsg(appmsgport))
  459.             {
  460.                int i;
  461.                char *exttext = global.text[CONFIG_EXT];
  462.                int extlen = strlen(exttext);
  463.                int argnmln;
  464.                struct WBArg *argptr;
  465.                BYTE *argname;
  466.                char *projname; /* point to proj.DICE if found */
  467.  
  468.                argptr = appmsg->am_ArgList;
  469.                for (i = 0; i < appmsg->am_NumArgs; i++)
  470.                {
  471.                   int aproctype = 0;
  472.                   /* takes on values: 0  no defined processing           */
  473.                   /*                  1  add file name to list           */
  474.                   /*                  2  read in a project script        */
  475.                   /*                  3  go to dir - request script name */
  476.                   projname = NULL;
  477.                   argname = argptr->wa_Name;
  478.                   if (*argname) /* argument is a file, not a directory */
  479.                   {
  480.                      aproctype = 1; /* simple file */
  481.                      if ((argnmln = strlen(argname)) > extlen)
  482.                         if (!stricmp(argname + argnmln - extlen, exttext))
  483.                         {
  484.                            aproctype = 2; /* read project file */
  485.                            projname = (char *)argname;
  486.                         }
  487.                   }
  488.                   else /* directory - see if we can find a default project */
  489.                   {
  490.                      aproctype = 3; /* simple directory */
  491.                   }
  492.  
  493.                   if (aproctype >= 2) /* see if it's OK to change directory */
  494.                   {
  495.                      if (save_current(1) == 0)
  496.                      {
  497.                         BPTR dlock;
  498.                         go_dir(argptr->wa_Lock);
  499.                         if ((dlock = DupLock(argptr->wa_Lock)) != NULL)
  500.                         {
  501.                            UnLock(global.homedir);
  502.                            global.homedir = dlock;
  503.                         }
  504.                         else
  505.                            aproctype = 0; /* READ wouldn't work... */
  506.                      }
  507.                      else
  508.                         /* give up on this one */
  509.                         aproctype = 0;
  510.                   }
  511.  
  512.                   if (aproctype == 3) /* see if there is a default project */
  513.                   {
  514.                      if (Examine(argptr->wa_Lock, &vmfib))
  515.                      {
  516.                         BPTR dlock;
  517.                         strcpy(appwinbuff, vmfib.fib_FileName);
  518.                         strcat(appwinbuff, exttext);
  519.                         if (dlock = Lock(appwinbuff, SHARED_LOCK))
  520.                         {
  521.                            aproctype = 2; /* default project exists */
  522.                            projname = appwinbuff;
  523.                            UnLock(dlock);
  524.                         }
  525.                      }
  526.                   }
  527.  
  528.                   /* now we've figure out how to process the object - do it */
  529.                   switch (aproctype)
  530.                   {
  531.                      case 1: /* simple filename to add to list */
  532.              {
  533.                         int match = 0; /* directory match ? */
  534.                         int pdir = 0;  /* prepend directory name? */
  535.                         int l;
  536.                         char *p;
  537.                         BPTR fplock = 0, wplock =0;
  538.  
  539.                         if (SameLock(global.workdir, argptr->wa_Lock)
  540.                                == LOCK_SAME)
  541.                            match = 1;
  542.                         else
  543.                         {
  544.                            fplock = ParentDir(argptr->wa_Lock);
  545.                            if (SameLock(fplock, global.workdir)
  546.                                   == LOCK_SAME)
  547.                {
  548.                               match = 2;
  549.                               pdir = 1;
  550.                }
  551.                            else
  552.                            {
  553.                               wplock = ParentDir(global.workdir);
  554.                               if (SameLock(wplock, argptr->wa_Lock)
  555.                                      == LOCK_SAME)
  556.                                  match = 3;
  557.                               else
  558.                               {
  559.                                  if (SameLock(wplock, fplock)
  560.                         == LOCK_SAME)
  561.                  {
  562.                                     match = 4;
  563.                     pdir = 1;
  564.                  }
  565.                               }
  566.                            }
  567.                         }
  568.  
  569.                         *appwinbuff = '\0';
  570.                         if (match)
  571.                         /* Match   Filename
  572.                              0     <absolute path>/wa_Name
  573.                              1     wa_Name
  574.                              2     fparent/wa_Name
  575.                              3     /wa_Name
  576.                              4     /fparent/wa_Name
  577.                         */
  578.                         {
  579.                            if (match > 2)  /* 3 or 4 */
  580.                               strcpy(appwinbuff, "/");
  581.                            if (pdir)       /* parent dir name required */
  582.                            {
  583.                   if (Examine(argptr->wa_Lock, &vmfib))
  584.                   {
  585.                      strcat(appwinbuff, vmfib.fib_FileName);
  586.                                  /* note: fplock is valid when pdir = 1 */
  587.                      if (fplock == 0) /* name is root */
  588.                                     strcat(appwinbuff, ":");
  589.                   }
  590.                               else
  591.                                  match = 0;  /* no path name - forget it */
  592.                            }
  593.                         }
  594.             else
  595.                            if (NameFromLock(argptr->wa_Lock, appwinbuff, 255))
  596.                   pdir = 1;  /* have path in appwinbuff now */
  597.  
  598.                         /* path (if any) in appwinbuff, name in wa_Name */
  599.                         l = strlen(appwinbuff);
  600.                         p = appwinbuff+l;
  601.  
  602.                         if (pdir)  /* parent dir name in appwinbuff */
  603.             /* append "/" if approriate */
  604.                            if (*(p-1) != ':')
  605.                            {
  606.                               strcpy(p, "/");
  607.                               p++;
  608.                            }
  609.                         if (strlen(argptr->wa_Name) < (255-l))
  610.                            strcpy(p, argptr->wa_Name);
  611.                         handle_list(global.filelist, NULL, CLASS_ADD, appwinbuff, 0);
  612.  
  613.             if (fplock)
  614.                UnLock(fplock);
  615.             if (wplock)
  616.                UnLock(wplock);
  617.                         break;
  618.  
  619.              }
  620.                      case 2: /* project script: proj.DICE */
  621.                      {
  622.                         char cmdbuff[266];
  623.  
  624.                         strcpy(cmdbuff, "READ ");
  625.                         strcat(cmdbuff, projname);
  626.                         do_command(cmdbuff);
  627.                         break;
  628.                      }
  629.                      case 3: /* go to directory and prompt for file */
  630.                      {
  631.                         char cmdbuff[] = "READ ?";
  632.                         do_command(cmdbuff);
  633.                         break;
  634.                      }
  635.                   }
  636.                   argptr++;
  637.                }
  638.                ReplyMsg((struct Message *)appmsg);
  639.             }            
  640.          }
  641.  
  642.          /* See if they want us to do any rexx commands */
  643.          if (mask & (1 << RexxSigBit))
  644.             ProcessRexxCommands(NULL);
  645.  
  646.          /* we had to defer this because it messes up no end if you try to */
  647.          /* change the menus while processing a menupick intuimessage      */
  648.          if (global.unghost) /* set by Read or New commands */ 
  649.          {
  650.             if (global.filename[0]) /* Read or New might have failed... */
  651.             {  /* but they didn't */
  652.                unghost_menus();
  653.                uncover_window();
  654.             }
  655.             else
  656.             {  /* or else they did */
  657.                ghost_menus();
  658.                cover_window();
  659.             }
  660.          }
  661.       }
  662.       if (appwindow)  RemoveAppWindow(appwindow);
  663.       if (appmsgport) DeleteMsgPort(appmsgport);
  664.       set_gadgets(0);
  665.       free_gadlist(global.gadlist);
  666.       DestroyWindow();
  667.    }
  668.  
  669.    CleanUp_RenderInfo(&global.ri);
  670. /* this is where the open/close window loop ends */
  671.  
  672. }
  673.    UnLock(global.workdir);
  674.    UnLock(global.homedir);
  675.  
  676.    if (global.freq && (AslBase != NULL)) FreeFileRequest(global.freq);
  677.  
  678.    if (GadToolsBase  != NULL) CloseLibrary(GadToolsBase);
  679.    if (AslBase       != NULL) CloseLibrary(AslBase);
  680.    if (ArpBase       != NULL) CloseLibrary(ArpBase);
  681.    if (WorkbenchBase != NULL) CloseLibrary(WorkbenchBase);
  682.    return(0);
  683. }
  684.  
  685. /***********************************************************************************
  686.  * Procedure: CreateWindow
  687.  * Synopsis:  rc = CreateWindow();
  688.  * Purpose:   Create the window on the current screen using the current environment
  689.  ***********************************************************************************/
  690. int CreateWindow()
  691. {
  692.    struct NewWindow nw;
  693.  
  694.    struct TagItem    wintags[] = {
  695.       { WA_PubScreen,        (ULONG)global.screen },
  696.           /* The screen we want to be on */
  697.       { WA_PubScreenFallBack,    (ULONG)TRUE    }, /* Or workbench if not */
  698.       { TAG_DONE,        (ULONG)0    }
  699.    };
  700.  
  701.  
  702.    memset(&nw, 0, sizeof(nw));
  703.  
  704.    nw.Width      = global.width;
  705.    nw.Height     = global.height;
  706.    nw.LeftEdge   = (global.ri.ScreenWidth  - nw.Width ) / 2;
  707.    nw.TopEdge    = (global.ri.ScreenHeight - nw.Height) / 2;
  708.    nw.MinWidth   = 4*BUTTON_WIDTH;
  709.    nw.MinHeight  = 110;
  710.    nw.MaxWidth   = 0xffff;
  711.    nw.MaxHeight  = 0xffff;
  712.  
  713.    if ((nw.Width < 0) || (nw.Height < 0))
  714.       return(1);
  715.    nw.DetailPen  = nw.BlockPen = -1;
  716. if (global.parsefail)
  717. {
  718.    nw.IDCMPFlags = CLOSEWINDOW;
  719.    nw.Flags      = WINDOWDEPTH    |
  720.                    WINDOWCLOSE    |
  721.                    WINDOWDRAG     |
  722.                    SIMPLE_REFRESH |
  723.                    ACTIVATE       |
  724.                    NOCAREREFRESH;
  725.  
  726. }
  727. else
  728. {
  729.    nw.IDCMPFlags = GADGETUP    |
  730.                    GADGETDOWN  |
  731.                    MENUPICK    |
  732.                    MOUSEMOVE   |
  733.                    VANILLAKEY  |
  734.                    NEWSIZE     |
  735.                    CLOSEWINDOW;
  736.    nw.Flags      = WINDOWDEPTH    |
  737.                    WINDOWSIZING   |
  738.                    WINDOWCLOSE    |
  739.                    WINDOWDRAG     |
  740.                    SIMPLE_REFRESH |
  741.                    ACTIVATE       |
  742.                    NOCAREREFRESH;
  743.  
  744. }
  745.    nw.Title      = global.title;
  746.    if (AslBase != 0)  /* public screens come with Dos 2.0... */
  747.       {
  748.       nw.Type       = PUBLICSCREEN;
  749.  
  750.       global.window = OpenWindowTagList(&nw, wintags);
  751.       if (global.screen)
  752.          UnlockPubScreen(NULL, global.screen);
  753.       }
  754.    else /* do the Dos 1.3 version */
  755.       {
  756.       nw.Type       = WBENCHSCREEN;
  757.       global.window = OpenWindow(&nw);
  758.       }
  759.  
  760.    if (global.window == NULL) return(2);
  761.    SetWindowTitles(global.window, global.title, global.title2);
  762.    global.rp = global.window->RPort;
  763.    enable_menu();
  764.    return(0);
  765. }
  766.  
  767. /***********************************************************************************
  768.  * Procedure: DestroyWindow
  769.  * Synopsis:  (void)DestroyWindow();
  770.  * Purpose:   Make the current window go away
  771.  ***********************************************************************************/
  772. void DestroyWindow()
  773. {
  774.    free_menus(global.menu);
  775.    CloseWindow(global.window);
  776. global.window = 0; /* do we need this? */
  777. }
  778.  
  779.  
  780. /***********************************************************************************
  781.  * Procedure: SkipAss
  782.  * Synopsis:  p = SkipAss(ptr)
  783.  * Purpose:   Skip whitespace in tooltype assignment
  784.  ***********************************************************************************/
  785. char * SkipAss(const char *ptr)
  786. {
  787.    while (*ptr && *ptr != '=')
  788.       ptr++;
  789.    if (*ptr == '=')
  790.    {
  791.       for (ptr++; *ptr == ' ' || *ptr == '\t'; ptr++)
  792.          ;
  793.    }
  794.    return(ptr);
  795. }
  796.  
  797. /***********************************************************************************
  798.  * Procedure: DoRexxCommand
  799.  * Synopsis:  rc = DoRexxCommand(msg, port, arg, pres)
  800.  * Purpose:   Handling executing a rexx command
  801.  ***********************************************************************************/
  802. long DoRexxCommand(void *msg,              /* RexxMsg structure if we need it      */
  803.                    struct MsgPort *port,   /* MsgPort structure if we need it      */
  804.                    char *arg0,             /* arg0                                 */
  805.                    char **pres             /* where to put our result if rc==0     */
  806.                   )
  807. {
  808.    if (!global.rexxinter)
  809.       global.inrexx = 1;      /* controls some error processing         */
  810.    global.rexxmsgs = 1;       /* always get messages & return codes     */
  811.    global.rexxrs[0] = '\0';   /* clear any leftover value               */
  812.    global.rexxrc = 0;         /* presumed innocent until proven guilty  */
  813.    InitSession();             /* ensure console window will be around   */
  814.  
  815. strcpy(global.rexxrs, "Command OK");
  816.    do_command(arg0);
  817.  
  818.    global.rexxmsgs = 0;
  819.    global.inrexx = 0;         /* revert to non-rexx error handling      */
  820.    if (global.rexxrc == 0)
  821.       *pres = global.rexxrs;  /* result string (might point to "")      */
  822.    else
  823.       global.rexxrc += 1;     /* to match numbering in documentation    */
  824.    return(global.rexxrc);
  825. }
  826.  
  827.